<!DOCTYPE html>  
<html>  
  <head>  
    <title>View Animation</title>  
    <link rel="stylesheet" href="https://openlayers.org/en/v4.2.0/css/ol.css" type="text/css">  
    <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->  
    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>  
    <script src="https://openlayers.org/en/v4.2.0/build/ol.js"></script>  
  </head>  
  <body>  
    <div id="map" class="map"></div>  
    <button id="rotate-left" title="Rotate clockwise">↻</button>  
    <button id="rotate-right" title="Rotate counterclockwise">↺</button>  
    <button id="pan-to-london">Pan to London</button>  
    <button id="elastic-to-moscow">Elastic to Moscow</button>  
    <button id="bounce-to-istanbul">Bounce to Istanbul</button>  
    <button id="spin-to-rome">Spin to Rome</button>  
    <button id="fly-to-bern">Fly to Bern</button>  
    <button id="rotate-around-rome">Rotate around Rome</button>  
    <button id="tour">Take a tour</button>  
    <script>  
      //城市地理坐标位置  
     var london = ol.proj.fromLonLat([-0.12755, 51.507222]);  
      var moscow = ol.proj.fromLonLat([37.6178, 55.7517]);  
      var istanbul = ol.proj.fromLonLat([28.9744, 41.0128]);  
      var rome = ol.proj.fromLonLat([12.5, 41.9]);  
      var bern = ol.proj.fromLonLat([7.4458, 46.95]);  
  
      //初始化地图视图  
      var view = new ol.View({  
        center: istanbul,  
        zoom: 6  
      });  
  
      //初始化地图  
      var map = new ol.Map({  
        target: 'map',  
        layers: [  
          new ol.layer.Tile({  
            preload: 4,  
            source: new ol.source.OSM()  
          })  
        ],  
  
        /*  
           loadTilesWhileAnimating:  
           When set to true, tiles will be loaded during animations.   
           当设置为true的时候，瓦片会在执行动画的时候加载  
           This may improve the user experience, but can also make animations stutter on devices with slow memory.  
           这会提高用户体验，但也会使动画在内存比较小的设备上执行的时候变得卡顿  
           Default is false.  
           默认为false  
        */  
         
        loadTilesWhileAnimating: true,  
        view: view  
      });  
  
      //反弹函数  
     function bounce(t) {  
        var s = 7.5625, p = 2.75, l;  
        if (t < (1 / p)) {  
          l = s * t * t;  
        } else {  
          if (t < (2 / p)) {  
            t -= (1.5 / p);  
            l = s * t * t + 0.75;  
          } else {  
            if (t < (2.5 / p)) {  
              t -= (2.25 / p);  
              l = s * t * t + 0.9375;  
            } else {  
              t -= (2.625 / p);  
              l = s * t * t + 0.984375;  
            }  
          }  
        }  
        return l;  
      }  
  
      //伸缩函数  
      function elastic(t) {  
        return Math.pow(2, -10 * t) * Math.sin((t - 0.075) * (2 * Math.PI) / 0.3) + 1;  
      }  
  
      //根据按钮id来执行相应的回调函数  
      function onClick(id, callback) {  
        document.getElementById(id).addEventListener('click', callback);  
      }  
  
      //左旋  
      onClick('rotate-left', function() {  
        view.animate({  
          rotation: view.getRotation() + Math.PI / 2  
        });  
      });  
  
      //右旋  
      onClick('rotate-right', function() {  
        view.animate({  
          rotation: view.getRotation() - Math.PI / 2  
        });  
      });  
  
      //围绕罗马旋转  
      onClick('rotate-around-rome', function() {  
        view.animate({  
          rotation: view.getRotation() + 2 * Math.PI,  
          anchor: rome  
        });  
      });  
  
      //平移到伦敦  
      onClick('pan-to-london', function() {  
        view.animate({  
          center: london,  
          duration: 2000  
        });  
      });  
  
      //拉伸到莫斯科  
      onClick('elastic-to-moscow', function() {  
        view.animate({  
          center: moscow,  
          duration: 2000,  
          easing: elastic  
        });  
      });  
  
      //弹跳到伊斯坦布尔  
      onClick('bounce-to-istanbul', function() {  
        view.animate({  
          center: istanbul,  
          duration: 2000,  
          easing: bounce  
        });  
      });  
  
      //旋转到罗马  
      onClick('spin-to-rome', function() {  
        view.animate({  
          center: rome,  
          rotation: 2 * Math.PI,  
          duration: 2000  
        });  
      });  
  
      //飞行函数  
      function flyTo(location, done) {  
        var duration = 2000;  
        var zoom = view.getZoom();  
        var parts = 2;  
        var called = false;  
        function callback(complete) {  
          --parts;  
          if (called) {  
            return;  
          }  
          if (parts === 0 || !complete) {  
            called = true;  
            done(complete);  
          }  
        }  
        view.animate({  
          center: location,  
          duration: duration  
        }, callback);  
        view.animate({  
          zoom: zoom - 1,  
          duration: duration / 2  
        }, {  
          zoom: zoom,  
          duration: duration / 2  
        }, callback);  
      }  
  
      //飞行到柏林  
      onClick('fly-to-bern', function() {  
        flyTo(bern, function() {});  
      });  
  
      //漫游  
      function tour() {  
        var locations = [london, bern, rome, moscow, istanbul];  
        var index = -1;  
        function next(more) {  
          if (more) {  
            ++index;  
            if (index < locations.length) {  
              var delay = index === 0 ? 0 : 750;  
              setTimeout(function() {  
                flyTo(locations[index], next);  
              }, delay);  
            } else {  
              alert('Tour complete');  
            }  
          } else {  
            alert('Tour cancelled');  
          }  
        }  
        next(true);  
      }  
  
      onClick('tour', tour);  
    </script>  
  </body>  
</html>  